package com.xxlie.auth.interceptor;

import com.xxlie.core.common.StringUtils;
import com.xxlie.auth.common.UserLoginContext;
import com.xxlie.auth.domain.Log;
import com.xxlie.auth.domain.User;
import com.xxlie.auth.service.LogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 *
 *
 * @author xxlie.com
 * @since 2017/8/5
 */
@Component
public class LogInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private LogService logService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        String requestRri = request.getRequestURI();
        String uriPrefix = request.getContextPath();

        if (handler instanceof HandlerMethod) {
            HandlerMethod method = (HandlerMethod) handler;
            OperationLog operationLog = method.getMethod().getAnnotation(OperationLog.class);

            if ((StringUtils.startsWith(requestRri, uriPrefix) && operationLog != null) || ex != null) {

                User user = UserLoginContext.getCurrentUser();
                if (user != null && user.getId() != null) {

                    StringBuilder params = new StringBuilder();
                    int index = 0;
                    for (Object param : request.getParameterMap().keySet()) {
                        params.append(index++ == 0 ? "" : "&").append(param).append("=");
                        params.append(StringUtils.abbr(StringUtils.endsWithIgnoreCase((String) param, "password")
                                ? "" : request.getParameter((String) param), 100));
                    }

                    Log log = new Log();
                    log.setType(ex == null ? Log.TYPE_ACCESS : Log.TYPE_EXCEPTION);
                    log.setCreateBy(user);
                    log.setCreateDate(new Date());
                    log.setRemoteAddr(StringUtils.getRemoteAddr(request));
                    log.setUserAgent(request.getHeader("user-agent"));
                    log.setRequestUri(request.getRequestURI());
                    log.setMethod(request.getMethod());
                    log.setParams(params.toString());
                    log.setException(ex != null ? ex.toString() : "");
                    logService.save(log);

                    logger.info("save log {type: {}, loginName: {}, uri: {}}, ", log.getType(), user.getUsername(), log.getRequestUri());

                }
            }

        }


    }
}
